Repository navigation
kernel: define SUPPORT_PRAGMA_UNUSED for clang - #619
Closed
cyclistmass wants to merge 1 commit into
Closed
cyclistmass wants to merge 1 commit into
cyclistmass wants to merge 1 commit into
Conversation
Member
…piler that implements it
SUPPORT_PRAGMA_UNUSED is #ifdef'd in ten places and #define'd in none, so the
`#pragma unused(...)' annotations it guards have never reached any compiler:
$ git grep -c SUPPORT_PRAGMA_UNUSED -- 'lisp-kernel/*.c'
lisp-kernel/arm-exceptions.c (936, 1002, 1305)
lisp-kernel/arm64-exceptions.c (1114, 1196, 1825)
lisp-kernel/ppc-exceptions.c (983, 1146, 1367, 1540)
$ git grep -n 'define[[:space:]]*SUPPORT_PRAGMA_UNUSED'
(nothing)
Each site says that a parameter forced on the function by a handler-dispatch
signature is deliberately unused -- do_hard_stack_overflow needs only xp,
do_spurious_wp_fault needs none of the three, allocate_no_stack needs none. The
intent is right and recorded; only the channel to the compiler is dead.
=== MEASURED, because #pragma unused is not a thing to reason about from memory
It is a Metrowerks/MPW-lineage extension and gcc and clang do not agree about
it. So it was measured rather than recalled, on the real do_hard_stack_overflow
shape, with a positive control (the same file WITHOUT the pragma, which must
emit `unused parameter' before any other result is interpretable). gcc 11.5.0
20240719 on x86_64 and aarch64, clang 15.0.7 on aarch64:
gcc 11.5.0 clang 15.0.7
recognised? NO YES
"ignoring '#pragma (no diagnostic
unused ' [-Wunknown- at all)
pragmas]"
suppresses `unused parameter'? NO (still 2) YES (2 -> 0)
diagnostics added 1 per site 0
-Wall -Wextra -Werror exit code 1 (2 errors -> 3) 0
Verbatim, gcc, with the pragma present:
B.c: In function 'do_hard_stack_overflow':
B.c: warning: ignoring '#pragma unused ' [-Wunknown-pragmas]
B.c:53: warning: unused parameter 'area' [-Wunused-parameter]
B.c:67: warning: unused parameter 'addr' [-Wunused-parameter]
exit code: 0
Verbatim, clang, same file, same flags: no output, exit 0.
So an UNCONDITIONAL #define would be measurably worse than the dead guard: on
gcc it suppresses nothing and adds one -Wunknown-pragmas at each of the ten
sites, and turns a -Wall -Wextra -Werror build from 2 errors into 3. Hence
clang only.
Two more measurements that bear on the risk, both on clang 15.0.7:
* A pragma naming an identifier that does not exist is DIAGNOSED, not ignored:
"undeclared variable 'x' used as an argument for '#pragma unused'
[-Wignored-pragmas]". clang parses the argument list, so these annotations
stay honest as the code changes -- something -Wno-unused-parameter cannot
do.
* A pragma naming a parameter that IS used is silently accepted: no
diagnostic, exit 0 even under -Werror.
* At file scope the names are not in scope and clang warns twice and
suppresses nothing. All ten sites are inside a function body, which is
where it works.
=== Where the #define goes
lisp.h, because all three files include it first and this is a property of the
COMPILER, not of a platform -- putting it in the per-platform headers would mean
repeating a __clang__ test in each of them.
=== Relationship to -Wno-unused-parameter on the arm64 kernel
I added -Wno-unused-parameter to lisp-kernel/linuxarm64/Makefile in a separate
arm64 patch, and said there that what to do with the #pragma blocks was your
call. This is that follow-up, and it does NOT make the flag redundant:
linuxarm64/Makefile:11 is `CC = ${CROSS}gcc', so on our own kernel build this
patch changes nothing at all and the flag is still what suppresses the 78
-Wunused-parameter there. Measured, not assumed -- see below, where gcc's
warning census is bit-for-bit the same with and without this patch. The two are
complementary: the pragma covers the compiler that understands it, the flag
covers the one that does not.
=== The alternative, if you would rather not
Delete the ten #ifdef/#pragma/#endif blocks and keep warning suppression at the
build flags. That is a defensible call and a smaller thing to maintain; it just
throws away suppression that measurably works on clang, and clang is the
compiler the Darwin targets use. I have written the version I think is right;
either is easy from here and it is your tree.
=== NOT TESTED
⛔ Of the three files this affects, only arm64-exceptions.c has been compiled.
RED-then-GREEN on the real translation unit, aarch64, tree at the pin:
lisp-kernel/arm64-exceptions.c, -Wall -Wextra, otherwise the Makefile's own
flags (-include ../platform-linuxarm64.h -DLINUX -DARM64 ... -g -O2 -Wno-format).
Three configurations, because the third is the one that justifies "clang only":
unused-param -Wunknown-pragmas total warn .o md5
RED gcc, no macro 19 0 61 96930241
GREEN gcc, no macro 19 0 61 96930241
COUNTER gcc, macro ON 19 3 64 96930241
RED clang, no macro 19 0 23 7d5242da
GREEN clang, macro ON 13 0 17 7d5242da
* clang 19 -> 13. Grouped by parameter name, so that "six warnings went
away" cannot be six DIFFERENT warnings:
addr 4->2 area 2->0 size 1->0 xp 4->3
info 1->1 instruction 1->1 param 1->1 signum 1->1 tcr 4->4
Total -6, and the three #pragma lines in the file name exactly six
identifiers: (area,addr) + (xp,area,addr) + (size) = 2+3+1. Every
parameter NOT named by a pragma is untouched.
* ZERO -Wignored-pragmas on the green clang run -- the check that every
identifier the three pragmas name really is in scope.
* gcc RED vs GREEN is BYTE-IDENTICAL output, because __clang__ is not
defined and the guard stays false. The -Wno-unused-parameter flag
therefore still does all the work on our own kernel build.
* COUNTER is what an unconditional #define would do to gcc: three
-Wunknown-pragmas, one per site, 61 -> 64 warnings, and not one
unused-parameter removed. Worse than the dead guard, measured rather than
predicted.
* THE .o md5 IS IDENTICAL in all three gcc configurations and in both clang
configurations. So this changes diagnostics and provably nothing else --
no generated code moves, on either compiler, with or without the macro.
* Positive control: the RED clang run emitted 19 > 0, i.e. the instrument was
seen reporting the un-suppressed state before the suppressed one was
believed.
* Reproduced on a second, independent pin tree by a red/green control
script that carries these gates.
NOT COMPILED, at all: arm-exceptions.c (ARM32) and ppc-exceptions.c -- I have no
ARM32 or PPC machine. Their seven sites were READ, and every identifier named
there is a parameter of the enclosing function, so I expect the same result --
but that is inspection, not a build.
Confidence: high that the #define is correct for clang and inert for gcc (red
and green both watched, on the real TU); high that it is a no-op for our own
kernel build; medium that the seven un-compiled sites are clean, on inspection
alone.
Signed-off-by: Mauro DiBenedetto <maurodibenedetto@gmail.com>
cyclistmass
force-pushed
the
kernel-three
branch
from
September 29, 2026 16:11
84aae00 to
d2e8376
Compare
Contributor
Author
|
Thank you. I have rebased this onto master and dropped two of the three commits, so what is left is one change.
The What remains is the |
Member
|
Committed as 89e1b3f. Thank you. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SUPPORT_PRAGMA_UNUSEDguards ten#pragma unused(...)annotations in the three*-exceptions.cfiles. Nothing in the tree defines it, so no compiler has ever seen those annotations.This patch defines it in
lisp.hfor clang only.#pragma unused-Wunknown-pragmasper siteunused parameterwarningAn unconditional define would add ten gcc warnings and remove none. On
arm64-exceptions.c, clang goes from 19 to 13unused parameterwarnings, and each of the six that disappear is a parameter that a pragma names. The object file md5 does not change on either compiler, so the patch changes diagnostics and nothing else.I compiled only
arm64-exceptions.c. I read the other seven sites and did not compile them.The commit message has the full measurement and its control.